package snuvm.venus;

import snuvm.*;
import snuvm.arm9.hardware.AddressErrorException;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.undo.*;
import java.text.*;
import java.util.*;
import java.io.*;

/*
Copyright (c) 2009-2010,  Jeongho Nah, Gangwon Jo, Jaejin Lee

Developed by 
	Jeongho Nah (jeongho"at"aces.snu.ac.kr)
	Gangwon Jo (gangwon"at"aces.snu.ac.kr)
	Jaejin Lee (jlee"at"cse.snu.ac.kr)


Permission is hereby granted to use this version of the code 
under the same terms as MARS, which has the following license:

--
Copyright (c) 2003-2008,  Pete Sanderson and Kenneth Vollmar

Developed by Pete Sanderson (psanderson"at"otterbein.edu)
and Kenneth Vollmar (kenvollmar"at"missouristate.edu)

Permission is hereby granted, free of charge, to any person obtaining 
a copy of this software and associated documentation files (the 
"Software"), to deal in the Software without restriction, including 
without limitation the rights to use, copy, modify, merge, publish, 
distribute, sublicense, and/or sell copies of the Software, and to 
permit persons to whom the Software is furnished to do so, subject 
to the following conditions:

The above copyright notice and this permission notice shall be 
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

(MIT license, http://www.opensource.org/licenses/mit-license.html)
 */

	/**
	  *  Creates the tabbed areas in the UI and also created the internal windows that 
	  *  exist in them.
	  *   @author Jaejin Lee, Jeongho Nah
	  **/
   
    public class VideoMMIOPane extends JPanel implements Observer, ComponentListener, WindowFocusListener, Runnable {
   
      private VenusUI mainUI;
      private int squareW = 9;
      private int squareH = 18;
      private int maxColumn = 80;
      private int maxRow = 20;
      private int baseAddress = Globals.memory.externBaseAddress;
      private int dataLengthInByte = 4;
      private int currentCharData = 0; // ch + R + G + B
      private char character = 0;      

    /**
      *  Constructor for the EditPane class. 
   	**/
       public VideoMMIOPane(VenusUI appFrame){
         super(new BorderLayout());
         this.mainUI = appFrame;
         mainUI.editor = new Editor(mainUI);
      	// We want to be notified of editor font changes! See update() below.
         Globals.getSettings().addObserver(this);
         new Thread(this).start();
       }
      	/**
      	 *  Update, if source code is visible, when Font setting changes.
      	 *  This method is specified by the Observer interface.
      	 */
          
          public void paintComponent(Graphics g) {
        	  super.paintComponent(g);
  
        	  if (Globals.videoOutOn == false) {
        		  baseAddress = Globals.memory.externBaseAddress;
            	  for (int row = 0; row < maxRow; ++row) {
            		  for (int column = 0; column < maxColumn; ++column) {
           				  g.setColor(new Color(0, 0, 0));
           				  g.fillRect(column*squareW,row*squareH,squareW,squareH);
            		  }
            	  }
            	  g.setColor(new Color(255, 0, 0));
            	  g.drawString("Check out Video-Out signal! (SWI #45)", 70, 70);
        	  }
        	  else {
        		  baseAddress = Globals.memory.externBaseAddress;
	        	  for (int row = 0; row < maxRow; ++row)
	        	  {
	        		  for (int column = 0; column < maxColumn; ++column, baseAddress+=1) {
	        			  try {
	        				  currentCharData = Globals.memory.get(baseAddress, dataLengthInByte);
	        				  // get character
	        				  character = (char)(currentCharData & 0xff);
	        				  g.setColor(new Color(0, 0, 0)); // black background
	        				  g.fillRect(column*squareW,row*squareH,squareW,squareH);

	        				  g.setColor(new Color(250, 250, 250));
	        				  g.drawString(String.valueOf(character), column*squareW, row*squareH+squareH-2); //-2 to adust screen position, nothing special
	        			  }
	        			  catch(AddressErrorException e) {
	        				  // Surpressed
	        			  }
	        		  }
	        	  }
        	  }
          }
          public void update(Observable fontChanger, Object arg) {
          }
          protected void refresh() {
        	  repaint();
          }
          protected void updateBackground() {
          }

          public void componentShown(ComponentEvent e) {
              repaint();
          }
           
          public void componentHidden(ComponentEvent e) {
              refresh();
          }
          
          public void componentMoved(ComponentEvent e) {
              repaint();
          }
          
          public void componentResized(ComponentEvent e) {
              repaint();
          }
          
          public void windowGainedFocus(WindowEvent e) {
              refresh();
          }
          
          public void windowLostFocus(WindowEvent e) {
              refresh();
          }
          public void run() {
              try {
                  while (true) {
                	  if (Globals.videoOutOn == false)
                		  Thread.sleep(60000); // 1 min.
                	  else {
                		  Thread.sleep((int)1000/Globals.videoRefreshRate); // (1/xxHz)*1000
                	  }
                	  repaint();
                  }
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
   }